Recompose API
在文档中, HOC 指的是一个函数接收一个 React 组件,返回另一个新的 React 组件
1 | const EnhancedComponent=hoc(BaseComponent) |
有时是可以组合的
1 | const composedHoc=compose(hoc1,hoc2,hoc3) |
绝大多数的 Recompose 助手函数都是返回 hoc的函数
Higher-order components
mapProps
1 | mapProps( |
接收一个函数,映射拥有者的 props成为新的 props 集合, 并传递给 baseComponent.mapProps()
和其他的函数式工具可以很好的一起工作, 例如 Recomopose 没有omitProps()
函数,但是可以很容易的使用 lodash 的函数omit()
1 | const omitProps = keys => mapProps(props => omit(keys, props)) |
withProps
1 | withProps( |
新创建的props 和 owner props 合并
withPropsOnChange()
1 | withPropsOnChange( |
只有在 shouldMapKeys 发生变化时才可以创建新的 props. 确保 createProps 内的计算只有在必要的情况下才进行.
withHandlers()
1 | withHandlers( |
接收一组 handler creator 或者是 工厂函数. 这些函数都是高阶函数, 接收一组 props,返回操作函数
这么做,就是让 handler 通过闭包访问当前的 props,但是又不用改变函数的签名
传递给组件的handlers都是 immutable 属性, 在渲染器中会一直保持不变.这么做避免了在函数式组件中创建函数的一个缺陷, 就是原先的函数式组件中,每次渲染都会创建新的 handler,打断了使用shouldComponentUpdate()
函数通过判读 props 变化的优化措施. 所以在创建 handler 时最好使用 withHandlers()
,mapProps
和withProps
每次会创建新的 handler
实例:
1 | const enhance = compose( |
defaultProps()
1 | defaultProps( |
default 的 props 会和 owner props合并,但是owner props 的优先级更高,有相同属性的,不会被替换
renameProps()
1 |
|
Rename 单个属性
renameProps()
:更改多个属性名
withState()
1 | withState( |
传递两个额外的 props 到 base component: state value和一个 更新 state value 的函数, state updater 的签名如下:
1 |
|
第一个形式接收之前的state,映射为新的 state value. withState()
和withHadlers()
一起创建特定的 updater 函数. 例如
1 |
|
第二种形式接收单个值, 被作为新的 state
两种形式都接受可选的参数,这个参数是一个回调函数, 一旦setState()
完成,组件重新渲染,回调函数会执行.
初始值是必须的. 要么是 state 值, 或者是从初始 props 返回的初始 State.
withStateHandlers()
1 | withStateHandlers( |
传递 state对象属性和 immutable 版本的 updater 函数到 base component
每个 state updater 函数接收state,props和 payload必须返回新的 state 或者 undefined. 新的 state 和之前的 state 进行浅层比较, 如果返回 undefined,组件就不会重新渲染.
实例:
1 | const Counter = withStateHandlers( |
withReducer()
1 |
|
和withState()
类似,但是使用的是 reducer 函数. reducer 函数接收一个 state,一个 action, 返回一个新的 state. 之后新的 state 被应用
branch()
1 | branch( |
接收一个检测函数, 和两个高阶组件, test 函数接受 owner 的 props.如果返回的是 true, left
高阶组件被应用到 basecomponent, 反之,right
高阶组件被应用的 base component . 如果没有提供right
高阶组件, 返回包装的组件
renderComponent()
1 | renderComponent( |
接受一个组件, 返回高阶组件版本.
和其他的期待高阶组件的助手函数联合使用,例如branch()
:
1 |
|
renderNothing()
1 | renderNothing: HigherOrderComponent |
总是渲染null
的高阶组件
也是和其他期待高阶组件的助手函数一起工作
1 | // `hasNoData()` is a function that returns true if the component has |
shouldUpdate()
1 | shouldUpdate( |
高阶组件版本的 shouldComponentUpdate()
,test 函数接受当前的props和下一个 props
pure()
1 | pure: HigherOrderComponent |
阻止组件更新,除非是 props 发生变化. 使用shallowEquall()
检测变化.
onlyUdateForKeys()
1 |
|
阻止组件更新,只有在对应的 props中给定key的部分发生变化时才能执行更新. 使用的是shallowEqual()
检测变化
这个方法对于优化是最好的, 因为只关心特定的 props 部分.
实例:
1 | /** |
onlyUpdateForPropTypes()
工作方式和onlyUpdateForKeys()
类似,只是 props keys 是从 base component 的propTypes
中获取的,和setPropTypes()
一起非常有用.
如果base component 没有任何的propTypes
,组件不会执行任何更新操作. 这可能不是想要的结果,所以会在终端打印警告信息
1 | import PropTypes from 'prop-types'; // You need to import prop-types. See https://facebook.github.io/react/docs/typechecking-with-proptypes.html |
withContext()
1 | withContext( |
为子组件提供上下文.
getContext()
1 | getContext( |
从上下文中获取值并以 props 的形式传递.
lifycycle()
1 | lifecycle( |
这是高阶组件版本的React.Component()
,支持除了render()
之外的所有Component
API, render()方式是默认实现的. 任何lifecycle()
方法引起的 state改变, 会传递给包装组件
实例:
1 | const PostsList = ({ posts }) => ( |
toClass()
1 | toClass:HigherOrderComponent |
接收一个函数组件,包装成一个类. 如果是已经是一个类,就直接返回了
Sattic property helpers
这些方法不仅仅是要返回新的组件, 还改变了组建的属性
setStatic()
1 | setStatic( |
为 base component 赋予propTypes
属性
setDisplayName
1 | setDisplayName( |
赋予displayName
属性
Utilities
Recompose 包含一些额外的助手, 不是高阶组件,但是仍然非常有用
compose()
1 | compose(...functions: Array<Function>): Function |
把多个高阶组件组合成一个. 这个方法和 Redux 中的 compose()
, lodash-fp的 flowRight()
, Ramda 的compose()
工作原理是类似的.
getDisplayName()
1 | getDisplayName( |
返回 React 组件的显示名
wrapDisplayName()
1 | wrapDisplayName( |
返回显示名包装的React 组件.
shallowEqual()
1 | shallowEqual(a:Object,b:Object):boolean |
isClassComponent()
1 | isClassComponent(value:any):boolean |
createSink()
1 | createSink(callback:(props:Object)=>void):ReactClass |
什么也渲染,仅仅调用回调函数
componentFromProp()
1 | componentFromProp(propName: string): ReactFunctionalComponent |
创建一个组件以 props的形式接收另一个组件, 并使用剩余的 props 渲染这个组件
1 | const enhance = defaultProps({ component: 'button' }) |
nest()
1 | nest( |
返回嵌套的组件
1 | // Given components A, B, and C |
hoistStatics()
1 | hoistStatics(hoc: HigherOrderComponent): HigherOrderComponent |